import numpy as np
from sklearn import datasets
from sklearn.model_selection import  train_test_split

class LinearRegression:

    def __init__(self):
        self.all_ = None
        self.jieju_ = None
        self.xishu_ = None

    def fit(self, x_train, y_train):
        assert x_train.shape[0] == y_train.shape[0], \
            "行数相同"
        Xb = np.hstack([np.ones((len(x_train), 1)), x_train])
        self.all_ = np.linalg.inv(Xb.T.dot(Xb)).dot(Xb.T.dot(y_train))
        self.jieju_ = self.all_[0]
        self.xishu_ = self.all_[1:]
        return self

    def predict(self, x_test):
        assert self.all_ is not None and self.jieju_  is not None and self.xishu_ is not None , \
            "不能为空"
        assert x_test.shape[1] == len(self.xishu_), \
            "变量个数与参数不匹配"
        return self.__predict(x_test)

    def __predict(self, x_test):
        Xb = np.hstack([np.ones((len(x_test), 1)), x_test])
        return np.array(Xb.dot(self.all_))


    def score(self, x_test, y_test):
        assert x_test.shape[0] == y_test.shape[0], \
            "位数不一样"
        y_predict = self.__predict(x_test)
        return 1 - np.sum((y_predict - y_test) ** 2)/np.sum((y_test - np.mean(y_test)) ** 2)

    def __repr__(self):
        return "LinearRegression"


boston = datasets.load_boston()
x_train, x_test, y_train, y_test = train_test_split(boston.data, boston.target)
line = LinearRegression()
line.fit(x_train, y_train)
y_predict = line.predict(x_test)
print(line.jieju_)
print(line.score(x_test, y_test))